package aco_serial;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;

public class FileParser {
	
	private double[][] matrix = null;
	
	
	
	public FileParser(String matrixFileName) throws IOException {
		this.setMatrix(readMatrixFromFile(matrixFileName));
		
	}
	
	
	private final double[][] readMatrixFromFile(String fileName) throws IOException {

		final BufferedReader br = new BufferedReader(new FileReader(new File(fileName)));

		final LinkedList<Record> records = new LinkedList<Record>();

		boolean readAhead = false;
		String line;
		while ((line = br.readLine()) != null) {

			if (line.equals("EOF")) {
				break;
			}

			if (readAhead) {
				String[] split = sweepNumbers(line.trim());
				records.add(new Record(Double.parseDouble(split[1].trim()), Double
						.parseDouble(split[2].trim())));
			}

			if (line.equals("NODE_COORD_SECTION")) {
				readAhead = true;
			}
		}

		br.close();

		final double[][] localMatrix = new double[records.size()][records.size()];

		int rIndex = 0;
		for (Record r : records) {
			int hIndex = 0;
			for (Record h : records) {
				localMatrix[rIndex][hIndex] = calculateEuclidianDistance(r.x, r.y, h.x, h.y);
				hIndex++;
			}
			rIndex++;
		}

		return localMatrix;
	}
	
	
	
	private final String[] sweepNumbers(String trim) {
		String[] arr = new String[3];
		int currentIndex = 0;
		for (int i = 0; i < trim.length(); i++) {
			final char c = trim.charAt(i);
			if (((int) c) != 32) {
				for (int f = i + 1; f < trim.length(); f++) {
					final char x = trim.charAt(f);
					if (((int) x) == 32) {
						arr[currentIndex] = trim.substring(i, f);
						currentIndex++;
						break;
					} else if(f == trim.length() - 1){
						arr[currentIndex] = trim.substring(i, trim.length());
						break;
					}
				}
				i = i + arr[currentIndex-1].length();
			}
		}
		return arr;
	}
	
	
	
	
	private final double calculateEuclidianDistance(double x1, double y1, double x2, double y2) {
		return Math.abs((Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))));
	}
	
	
	
	public void setMatrix(double[][] matrix) {
		this.matrix = matrix;
	}


	public double[][] getMatrix() {
		if (this.matrix != null) {
			return matrix;
		}
		else {
			return null;
		}
	}



	static class Record {
		double x;
		double y;

		public Record(double x, double y) {
			super();
			this.x = x;
			this.y = y;
		}
	}



	public int getNumberOfNodes() {
		if (this.matrix != null) {
			return matrix.length;
		}
		return 0;
	}

}




